﻿
using Microsoft.AspNetCore.Mvc;
using Sykj.ViewModel;
using Sykj.IServices;
using Sykj.Components;
using System;
using Sykj.Infrastructure;
using System.Drawing;

namespace Sykj.Web.Api.v1
{
    /// <summary>
    /// 登录|注册  BJg
    /// </summary>
    public class AccountController : ApiController
    {
        #region 全局变量
        private readonly IUsers _users;
        private readonly IUserMember _userMember;
        private readonly ICacheService _cacheService;
        #endregion

        #region 构造方法
        /// <summary>
        /// 构造方法
        /// </summary>
        public AccountController(IUsers users, IUserMember userMember, ICacheService cacheService)
        {
            _users = users;
            _userMember = userMember;
            _cacheService = cacheService;
        }
        #endregion

        #region 帐号密码登录

        /// <summary>
        /// 登录  bjg
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <param name="passWord">密码</param>
        /// <param name="cId">设备ID</param>
        /// <returns></returns>
        [HttpPost("login")]
        public ApiResult Login(string userName, string passWord,string cId="")
        {
            if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(passWord))
            {
                return Failed("请输入用户名或者密码");
            }
            var result = _users.ValidateLogin(userName, passWord);
            if (result.success)
            {
                if (result.data.UserType != "UU")
                {
                    return Failed("用户未授权！");
                }

                var tm = new TokenModel()
                {
                    Uid = result.data.UserId.ToString(),
                    UserName = result.data.UserName,
                    Role = "UU",
                    Project = "App",
                    TokenType = "App"
                };
                string token = JwtHelper.IssueJWT(tm);

                if (!string.IsNullOrWhiteSpace(cId))
                {
                    PushService pushService = Factory.CreatePushService();
                    if (pushService != null)
                    {
                        pushService.BindAlias(cId, tm.Uid);
                    }
                }
                
                return DataResult(token);
            }
            else
            {
                return result;
            }
        }
        #endregion

        #region 短信登录

        /// <summary>
        /// 验证码登录 bjg
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <param name="code">短信验证码</param>
        /// <param name="cId">设备ID</param>
        /// <returns></returns>
        [HttpPost("logincode")]
        public ApiResult LoginCode(string userName, string code, string cId = "")
        {
            if (string.IsNullOrWhiteSpace(userName))
            {
                return Failed("手机号不能为空");
            }
            if (string.IsNullOrWhiteSpace(code))
            {
                return Failed("短信验证码不能为空");
            }
            //验证码
            string key = userName + Constant.LOGINCODE;
            var obj = _cacheService.GetCache<string>(key);
            if (obj == null)
            {
                return Failed("验证码异常！");
            }
            if (obj.ToString() != code)
            {
                return Failed("验证码错误！");
            }
            var model = _userMember.GetMemberModel(x => x.UserName == userName);
            if (model == null)
            {
                model.UserId = _userMember.Register(userName, "");
            }
            //Token码
            if (model.UserType != "UU")
            {
                return Failed("用户未授权！");
            }
            var tm = new TokenModel()
            {
                Uid = model.UserId.ToString(),
                UserName = userName,
                Role = "UU",
                Project = "App",
                TokenType = "App"
            };
            if (!string.IsNullOrWhiteSpace(cId))
            {
                PushService pushService = Factory.CreatePushService();
                if (pushService != null)
                {
                    pushService.BindAlias(cId, tm.Uid);
                }
            }
            string token = JwtHelper.IssueJWT(tm);
            return DataResult(token);
        }
        #endregion

        #region 帐号注册

        /// <summary>
        /// 注册  bjg
        /// </summary>
        /// <param name="userName">用户名/手机号</param>
        /// <param name="passWord">密码</param>
        /// <param name="code">短信验证码</param>
        /// <param name="inviteUserId">推广用户ID</param>
        /// <returns></returns>
        [HttpPost("register")]
        public ApiResult Register(string userName, string passWord, string code, int inviteUserId = 0)
        {
            if (string.IsNullOrWhiteSpace(userName))
            {
                return Failed("手机号不能为空");
            }
            if (string.IsNullOrWhiteSpace(code))
            {
                return Failed("验证码不能为空");
            }
            if (string.IsNullOrWhiteSpace(passWord))
            {
                return Failed("密码不能为空!");
            }
            if (passWord.Length < 6)
            {
                return Failed("密码不能低于6位!");
            }
            if (_users.IsExists(userName))
            {
                return Failed("用户名已经存在!");
            }
            //验证码
            string key = userName + "SMSCode";
            var obj = _cacheService.GetCache<string>(key);
            if (obj == null)
            {
                return Failed("输入短信验证码不正确！");
            }
            if (obj.ToString() != code)
            {
                return Failed("输入短信验证码不正确！");
            }
            //注册

            int userId = _userMember.Register(userName, passWord, "", "", "", "", inviteUserId);
            if (userId <= 0)
            {
                return Failed("用户注册失败，请联系管理员！");
            }

            var tm = new TokenModel()
            {
                Uid = userId.ToString(),
                UserName = userName,
                Role = "UU",
                Project = "App",
                TokenType = "App"
            };
            string token = JwtHelper.IssueJWT(tm);
            return DataResult(token);
        }

        #endregion

        #region 发送短信

        /// <summary>
        /// 发送注册短信 bjg
        /// </summary>
        /// <param name="phone">手机号</param>
        /// <param name="validateCode">验证码</param>
        /// <param name="sessionKey">会话key</param>
        /// <returns></returns>
        [HttpPost("sendsms")]
        public ApiResult SendSms(string phone, string validateCode, string sessionKey)
        {
            if (string.IsNullOrWhiteSpace(phone))
            {
                return Failed("手机号不能为空");
            }
            if (string.IsNullOrWhiteSpace(validateCode))
            {
                return Failed("验证码不能为空");
            }
            if (_users.IsExists(phone))
            {
                return Failed("该手机号已经被注册!");
            }
            string code = _cacheService.GetCache<string>(sessionKey);
            if (code == null)
            {
                return Failed("请输入图片验证码！");
            }
            if (validateCode.ToLower() != code.ToLower())
            {
                return Failed("图片验证码输入错误！");
            }

            Random rnd = new Random();
            int rand = rnd.Next(1000, 9999);
            string msg = string.Empty;
            //短信模板
            string content = string.Format(BaseConfig.GetValue("SMS_Content"), rand);

            ISmsServer smsServer = Factory.CreateSmsServer();
            bool b = smsServer.SendMsg(phone, content, ref msg);
            if (b)
            {
                string key = phone + "SMSCode";
                //存缓存
                _cacheService.SetCache(key, rand.ToString(), DateTime.Now.AddMinutes(2));
                _cacheService.RemoveCache(sessionKey);
                return Success("短信发送成功，请注意查收！");
            }
            else
            {
                return Failed("短信发送失败，原因:" + msg);
            }
        }

        /// <summary>
        /// 发送短信找回密码 bjg
        /// </summary>
        /// <param name="phone">手机号</param>
        /// <param name="validateCode">验证码</param>
        /// <param name="sessionKey">会话key</param>
        /// <returns></returns>
        [HttpPost("sendfindpwd")]
        public ApiResult SendFindpwd(string phone, string validateCode, string sessionKey)
        {
            if (string.IsNullOrWhiteSpace(phone))
            {
                return Failed("手机号码不能为空!");
            }
            string code = _cacheService.GetCache<string>(sessionKey);
            if (string.IsNullOrWhiteSpace(code) || validateCode.ToLower() != code.ToLower())
            {
                return Failed("图片验证码输入错误！");
            }
            if (!_users.IsExists(phone))
            {
                return Failed("该手机号尚未注册或绑定用户,请注册或者绑定用户");
            }
            Random rnd = new Random();
            int rand = rnd.Next(1000, 9999);
            string msg = string.Empty;
            //短信模板
            string content = string.Format(BaseConfig.GetValue("SMS_Content"), rand);

            ISmsServer smsServer = Factory.CreateSmsServer();
            bool b = smsServer.SendMsg(phone, content, ref msg);
            if (b)
            {
                string key = phone + "SMSCode";
                //存缓存
                _cacheService.SetCache(key, rand.ToString(), DateTime.Now.AddMinutes(2));
                _cacheService.RemoveCache(sessionKey);
                return Success("短信发送成功，请注意查收！");
            }
            else
            {
                return Failed("短信发送失败，原因:" + msg);
            }
        }

        /// <summary>
        /// 发送登录验证码 bjg
        /// </summary>
        /// <param name="phone">手机号</param>
        /// <param name="validateCode">验证码</param>
        /// <param name="sessionKey">会话key</param>
        /// <returns></returns>
        [HttpPost("sendlogincode")]
        public ApiResult SendLoginCode(string phone, string validateCode, string sessionKey)
        {
            if (string.IsNullOrWhiteSpace(phone))
            {
                return Failed("手机号码不能为空!");
            }
            string code = _cacheService.GetCache<string>(sessionKey);
            if (string.IsNullOrWhiteSpace(code) || validateCode.ToLower() != code.ToLower())
            {
                return Failed("图片验证码输入错误！");
            }
            if (!_users.IsExists(phone))
            {
                return Failed("该手机号尚未注册或绑定用户,请注册或者绑定用户");
            }
            Random rnd = new Random();
            int rand = rnd.Next(1000, 9999);
            string msg = string.Empty;
            //短信模板
            string content = string.Format(BaseConfig.GetValue("SMS_Content"), rand);

            ISmsServer smsServer = Factory.CreateSmsServer();
            bool b = smsServer.SendMsg(phone, content, ref msg);
            if (b)
            {
                string key = phone + Constant.LOGINCODE;
                //存缓存
                _cacheService.SetCache(key, rand.ToString(), DateTime.Now.AddMinutes(2));
                _cacheService.RemoveCache(sessionKey);
                return Success("短信发送成功，请注意查收！");
            }
            else
            {
                return Failed("短信发送失败，原因:" + msg);
            }
        }

        #endregion

        #region 找回密码

        /// <summary>
        /// 找回密码 bjg
        /// </summary>
        /// <param name="phone">手机号</param>
        /// <param name="newPassWord">新密码</param>
        /// <param name="againPassWord">新密码</param>
        /// <param name="code">验证码</param>
        /// <returns></returns>
        [HttpPost("findpassword")]
        public ApiResult FindPassword(string phone, string code, string newPassWord, string againPassWord)
        {
            if (string.IsNullOrWhiteSpace(phone))
            {
                return Failed("手机号不能为空");
            }
            //验证码
            string key = phone + "SMSCode";
            var obj = _cacheService.GetCache<string>(key);
            if (obj == null)
            {
                return Failed("验证码异常！");
            }
            if (obj.ToString() != code)
            {
                return Failed("验证码不正确！");
            }
            if (string.IsNullOrWhiteSpace(newPassWord))
            {
                return Failed("新密码不能为空");
            }
            if (newPassWord != againPassWord)
            {
                return Failed("两次输入的密码不一致");
            }
            var model = _users.GetModel(x => x.UserName == phone);
            model.Password = DESEncrypt.Encrypt(newPassWord);
            var b = _users.Update<Entity.Users>(model, true, x => x.Password);
            return AjaxResult(b);
        }

        #endregion

        #region 获取图片验证码

        /// <summary>
        /// 获取图片验证码 lx
        /// </summary>
        /// <returns></returns>
        [HttpGet("validatecode")]
        public ApiResult ValidateCode()
        {
            string checkCode = GetRandomCode(4);
            string key = Constant.CHECKCODE + Utils.GetGuid();
            //不启用Session
            _cacheService.SetCache(key, checkCode, DateTime.Now.AddMinutes(30));

            Bitmap image = CreateImage(checkCode);
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
            image.Dispose();
            Newtonsoft.Json.Linq.JObject jObject = new Newtonsoft.Json.Linq.JObject();
            jObject.Add("sessionKey", key);
            jObject.Add("img", $"data:image/jpeg;base64,{Convert.ToBase64String(ms.ToArray())}");
            return DataResult(jObject);
        }

        /// <summary>
        /// 生成随机字符
        /// </summary>
        /// <param name="codeCount"></param>
        /// <returns></returns>
        private string GetRandomCode(int codeCount)
        {
            string allChar = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,i,J,K,M,N,P,Q,R,S,T,U,W,X,Y,Z";
            string[] allCharArray = allChar.Split(',');
            string RandomCode = "";
            int temp = -1;

            Random rand = new Random();
            for (int i = 0; i < codeCount; i++)
            {
                if (temp != -1)
                {
                    rand = new Random(temp * i * ((int)DateTime.Now.Ticks));
                }

                int t = rand.Next(33);

                while (temp == t)
                {
                    t = rand.Next(33);
                }

                temp = t;
                RandomCode += allCharArray[t];
            }

            return RandomCode;
        }

        private Bitmap CreateImage(string checkCode)
        {
            int iwidth = (int)(checkCode.Length * 14);
            Bitmap image = new Bitmap(iwidth, 20);
            Graphics g = Graphics.FromImage(image);
            Font f = new Font("Arial ", 10);//, System.Drawing.FontStyle.Bold);
            Brush b = new SolidBrush(Color.Black);
            Brush r = new SolidBrush(Color.FromArgb(166, 8, 8));

            //g.FillRectangle(new System.Drawing.SolidBrush(Color.Blue),0,0,image.Width, image.Height);
            //			g.Clear(Color.AliceBlue);//背景色
            g.Clear(ColorTranslator.FromHtml("#99C1CB"));//背景色

            char[] ch = checkCode.ToCharArray();
            for (int i = 0; i < ch.Length; i++)
            {
                if (ch[i] >= '0' && ch[i] <= '9')
                {
                    //数字用红色显示
                    g.DrawString(ch[i].ToString(), f, r, 3 + (i * 12), 3);
                }
                else
                {   //字母用黑色显示
                    g.DrawString(ch[i].ToString(), f, b, 3 + (i * 12), 3);
                }
            }

            //for循环用来生成一些随机的水平线
            //			Pen blackPen = new Pen(Color.Black, 0);
            //			Random rand = new Random();
            //			for (int i=0;i<5;i++)
            //			{
            //				int y = rand.Next(image.Height);
            //				g.DrawLine(blackPen,0,y,image.Width,y);
            //			}

            return image;
        }

        #endregion

        #region 注册协议
        /// <summary>
        /// 注册协议 bjg
        /// </summary>
        /// <returns></returns>
        [HttpGet("registerprotocol")]
        public ApiResult RegisterProtocol()
        {
            string registerProtocol = BaseConfig.GetValue("RegisterProtocol");
            return DataResult(registerProtocol);
        }
        #endregion
    }
}